﻿#region Header

/***************************************************************************
Author : Krishan Kaliraman (www.sharedwith.me)  Date: 1 Aug 2012
***************************************************************************/

#endregion Header
using System;
using System.Linq;
using System.Globalization;
using System.Collections.Generic;
using System.Net;
using Common;
using System.Text;
using System.IO;
using System.Web.UI.HtmlControls;
using System.Configuration;
using System.Net.Mail;

namespace SprintChart
{
    public partial class DiscussPBI : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if(Request.QueryString["activityId"]==null)
            {
                RedirectToLoginPage();
            }
            string activityId = Request.QueryString["activityId"];            
            if (!string.IsNullOrEmpty(activityId))
            {
                ViewState["activityId"] = activityId;
            }
            else
            {
                RedirectToCurrentSprintPage();
            }
            if (!IsPostBack)
            {
                FillTfsUsers();
                FillTfsUsersForCCList();
                FillCommentCategories();
                DataBind();
            }

            string parentCommentId = Request.QueryString["parentCommentId"];
            if (!string.IsNullOrEmpty(parentCommentId))
            {
                ViewState["parentCommentId"] = parentCommentId;
            }
            FillActivityDetails(activityId);
        }

        private void RedirectToLoginPage()
        {
            Response.Redirect("~/LogOn.aspx");
        }

        private void RedirectToCurrentSprintPage()
        {
            Response.Redirect("~/CurrentSprint.aspx");
        }

        private void FillCommentCategories()
        {
            string activityTypesString = ConfigurationManager.AppSettings["activityTypes"];
            string[] activityTypes = activityTypesString.Split(new[] { ',' });
            List<CommentCategory> commentCategories = new List<CommentCategory>();
            int categoryId = 0;
            for(int counter=0;counter<activityTypes.Length; counter++)
            {
                categoryId = counter + 1;
                commentCategories.Add(new CommentCategory(){CommentCategoryId = categoryId.ToString(), CommentCategoryName = activityTypes[counter]});
            }
            ddlAbout.DataSource = commentCategories;
            ddlAbout.DataTextField = "CommentCategoryName";
        }

        private void FillTfsUsers()
        {
            ddlTfsUsers.DataSource = GetTfsUsers();
            ddlTfsUsers.DataTextField = "DisplayName";
        }

        private void FillTfsUsersForCCList()
        {
            ddlTfsUsersForCC.DataSource = GetTfsUsers();
            ddlTfsUsersForCC.DataTextField = "DisplayName";
            //ddlTfsUsersForCC.Attributes.Add("onchange", "getSelectedNamesForCCList();");
        }

        private List<TfsUser> GetTfsUsers()
        {            
            if (Application["TfsUsers"] == null)
            {
                Application["TfsUsers"] = TfsUserFactory.CreateTFsUserList();
            }
            List<TfsUser> listOfTfsUsers = new List<TfsUser>();
            listOfTfsUsers.Add(new TfsUser() { DisplayName = "- Select -" });
            listOfTfsUsers.AddRange((List<TfsUser>)Application["TfsUsers"]);
            return listOfTfsUsers;
        }        
        
        private void FillActivityDetails(string activityId)
        {           
            DiscussionActivity discussionActivity = Sprint.ReturnDiscussionActivity(activityId);
            FillActivityDetails(discussionActivity,false);
            activityLink.Text = discussionActivity.DiscussionActivityType+ " - " + discussionActivity.DiscussionActivityId + " ";
            activityLink.NavigateUrl = ConfigurationManager.AppSettings["TfsUrl"] + "/web/UI/Pages/WorkItems/WorkItemEdit.aspx?id=" + discussionActivity.DiscussionActivityId;
            txtComment.Focus();
        }

        private void FillActivityAttachmentDetails(DiscussionActivity discussionActivity)
        {
            // Create a new HtmlTable object.
            HtmlTable tblDocumentList = new HtmlTable {Width = "100%"};
            HtmlTableRow row;
            HtmlTableCell cell;
            foreach (ActivityAttachment attachment in discussionActivity.Attachments)
            {
                row = new HtmlTableRow();
                cell = new HtmlTableCell();
                cell.InnerHtml = "<a  href=\"" + attachment.Url +
                                 "\" style=\"font-family:Arial;font-size:9pt;\">" + attachment.Name + "</a>";
                row.Cells.Add(cell);
                tblDocumentList.Rows.Add(row);
            }
            if (discussionActivity.Attachments.Count > 0)
            {
                documentsDiv.Visible = true;
                documentsAttached.Controls.Clear();
                documentsAttached.Controls.Add(tblDocumentList);
            }
            else
            {
                documentsDiv.Visible = false;
            }
        }

        protected void btnSubmitComment_Click(object sender, EventArgs e)
        {
            string[] user = Page.User.Identity.Name.Split(new[] { '\\' });
            TfsUser currentTfsUser = GetCurrentTfsUser(user[1]);
            DiscussionItem discussionItem = new DiscussionItem();
            discussionItem.DiscussionActivityId = ViewState["activityId"].ToString();
            discussionItem.DiscussionText =Server.HtmlEncode( txtComment.InnerText);
            discussionItem.EnteredFor = ddlTfsUsers.Text;
            discussionItem.DiscussionType = ddlAbout.Text;
            discussionItem.EnteredBySmallName = currentTfsUser.DisplayName;            
            discussionItem.EntryDate =Convert.ToDateTime( DateTime.Parse(DateTime.Now.ToString(), null, DateTimeStyles.AdjustToUniversal).ToString());
            TfsUser toUser = GetToTfsUserFromListOfTfsUsers(ddlTfsUsers.Text);
            discussionItem.EmailTo = toUser.MailAddress;
            if (ViewState["parentCommentId"] != null)
            {
               discussionItem.ParentDiscussionEntryId = ViewState["parentCommentId"].ToString();
            }
            FillEmailCCToDiscussionItem(discussionItem);
            string filePath, comment;
            GetThePathOfFileToBeAttached(out filePath , out comment );
            DiscussionActivity discussionActivity=  AttachDocumentAndSubmitDiscussionItem(filePath,comment,discussionItem);
            discussionActivity.DiscussionHistory = discussionActivity.DiscussionHistory.OrderByDescending(d => d.EntryDate).ToList();
            SendDiscussionEmail(discussionActivity);
            FillActivityDetails(discussionActivity,false);
            ddlTfsUsers.SelectedIndex = 0;
            ddlTfsUsersForCC.SelectedIndex = 0;
            txtCC.Text = string.Empty;
            txtComment.InnerText = string.Empty;
        }

        private void FillEmailCCToDiscussionItem(DiscussionItem discussionItem)
        {
            List<TfsUser> listOfTfsUsers = GetTfsUsers();
            string[] listOfDisplayNames = GetListOfDisplayName(txtCC.Text);
            string ccEmailList = string.Empty;
            if(listOfDisplayNames.Length>0)
            {
                foreach(string displayName in listOfDisplayNames)
                {
                    foreach(TfsUser tfsUser in listOfTfsUsers)
                    {
                        if(displayName==tfsUser.DisplayName)
                        {
                            if(ccEmailList==string.Empty)
                            {
                                ccEmailList = ccEmailList + tfsUser.MailAddress;
                            }
                            else
                            {
                                ccEmailList = ccEmailList + "," + tfsUser.MailAddress;
                            }
                        }
                    }
                }
            }
            discussionItem.EmailCC = ccEmailList;
        }

        private string[] GetListOfDisplayName(string ccString)
        {
            string[] listOfTfsUserNamesinCCString = ccString.Split(new char[] { ',' });
            return listOfTfsUserNamesinCCString;
        }

        private TfsUser GetCurrentTfsUser(string tfsUserAccountName)
        {
            TfsUser currentTfsUser = null;            
            List<TfsUser> listOfTfsUsers = GetTfsUsers();
            currentTfsUser = listOfTfsUsers.Find(tfsUser => tfsUser.AccountName == tfsUserAccountName);
            return currentTfsUser;
        }

        private DiscussionActivity AttachDocumentAndSubmitDiscussionItem(string filePath, string fileComment, DiscussionItem discussionItem, NetworkCredential networkCredential)
        {
            DiscussionActivity discussionActivity = Sprint.UploadAttachmentAndEnterDiscussionItemToDiscussionActivity(filePath, fileComment, discussionItem ,networkCredential);
            return discussionActivity;
        }

        private void FillActivityDetails(DiscussionActivity discussionActivity , bool sortedByDescendingOrder)
        {
            if (sortedByDescendingOrder)
            {
                discussionActivity.DiscussionHistory =(discussionActivity.DiscussionHistory.OrderByDescending(discussionItem => discussionItem.EntryDate).ToList()); 
            }
            else
            {
                discussionActivity.DiscussionHistory =(discussionActivity.DiscussionHistory.OrderByDescending(discussionItem => discussionItem.EntryDate).ToList()).OrderBy(d => d.EntryDate).ToList();
            }
            string description = discussionActivity.DescriptionHtml;
            workItemDescriptionDiv.InnerHtml = description;
            string acceptanceCriteria = discussionActivity.AcceptanceCriteria;
            workItemAcceptanceCriteria.InnerHtml = acceptanceCriteria;
            FillActivityAttachmentDetails(discussionActivity);
            repeaterDiscussionHistory.DataSource = discussionActivity.DiscussionHistory;
            DataBind();
            FillEmailDetails(discussionActivity);
        }

        private void FillEmailDetails(DiscussionActivity discussionActivity)
        {
            if(IsPostBack)
            {
                return;
            }
            if(ViewState["parentCommentId"] !=null)
            {
                string parentCommentId = ViewState["parentCommentId"].ToString();
                DiscussionItem parentDiscussionItem = discussionActivity.DiscussionHistory.Find(discussionItem => discussionItem.DiscussionEntryId ==parentCommentId);
                ddlTfsUsers.Text = parentDiscussionItem.EnteredBySmallName;
                List<TfsUser> listOfTfsUsers = GetTfsUsers();
                ddlAbout.Text = parentDiscussionItem.DiscussionType;
                string ccEmailText = parentDiscussionItem.EmailCC;
                string[] listOfCCEmaillAddresses = ccEmailText.Split(new[] { ',' });
                foreach(string emailAddress in listOfCCEmaillAddresses)
                {
                    if( !string.IsNullOrEmpty(emailAddress.Trim()) )
                    {
                        foreach (TfsUser tfsUser in listOfTfsUsers)
                        {
                            if (emailAddress == tfsUser.MailAddress)
                            {
                                ccEmailText = ccEmailText.Replace(emailAddress, tfsUser.DisplayName);
                            }
                        }
                    }                    
                }
                foreach (TfsUser tfsUser in listOfTfsUsers)
                {
                    if (parentDiscussionItem.EmailTo == tfsUser.MailAddress)
                    {
                        if (!listOfCCEmaillAddresses.Contains(tfsUser.MailAddress))
                        {
                            ccEmailText = ccEmailText + "," + tfsUser.DisplayName;
                            ddlTfsUsersForCC.Text = tfsUser.DisplayName;
                        }
                    }
                }
                txtCC.Text = ccEmailText;
            }
        }

        private DiscussionActivity AttachDocumentAndSubmitDiscussionItem(string filePath, string fileComment, DiscussionItem discussionItem)
        {
            DiscussionActivity discussionActivity=Sprint.UploadAttachmentAndEnterDiscussionItemToDiscussionActivity(filePath, fileComment, discussionItem);
            return discussionActivity;
        }

        private void SendDiscussionEmail(DiscussionActivity discussionActivity)
        {
            DiscussionItem discussionItemEntered = discussionActivity.DiscussionEntered;
            MailMessage message = new MailMessage();
            message.IsBodyHtml = true;
            message.Subject =discussionActivity.DiscussionEntered.EnteredBySmallName+ " commented for " + discussionActivity.DiscussionEntered.DiscussionType + " on " +
                             discussionActivity.DiscussionActivityType + " " + discussionActivity.DiscussionActivityId;
            StringBuilder mailBody = new StringBuilder();
            mailBody.AppendFormat("<div style=\"font:1.2em; font-size:10pt; font-family:Arial, Helvetica, sans-serif;\">");
            mailBody.AppendFormat("Hello {0}", discussionItemEntered.EnteredFor);
            mailBody.AppendFormat("<br />");
            mailBody.AppendFormat("<br />" + discussionActivity.DiscussionEntered.EnteredBySmallName + " commented for " +discussionActivity.DiscussionEntered.DiscussionType + " on ");
            mailBody.AppendFormat("<a  href=\"" + ConfigurationManager.AppSettings["TfsUrl"] +"/web/UI/Pages/WorkItems/WorkItemEdit.aspx?id=" + discussionActivity.DiscussionActivityId+
                                  "\" style=\"font-family:Arial;font-size:15pt;\"> ");
            mailBody.AppendFormat(discussionActivity.DiscussionActivityType + " " + discussionActivity.DiscussionActivityId + "</a>");
            mailBody.AppendFormat("<br/>");
            mailBody.AppendFormat("<br/>");
            mailBody.AppendFormat("<table style=\"width:100%\">");
            mailBody.AppendFormat("<tr>");
            mailBody.AppendFormat("<td style=\"width:5%\">");
            mailBody.AppendFormat("</td>");
            mailBody.AppendFormat("<td style=\"width:95%\"><div>");
            mailBody.AppendFormat(Server.HtmlDecode( discussionItemEntered.DiscussionText));
            mailBody.AppendFormat("</div></td>");
            mailBody.AppendFormat("</tr>");
            if (discussionItemEntered.DocumentsAttached != null)
            {
                if (discussionItemEntered.DocumentsAttached.Count > 0)
                {
                    foreach (ActivityAttachment document in discussionItemEntered.DocumentsAttached)
                    {
                        mailBody.AppendFormat("<tr>");
                        mailBody.AppendFormat("<td style=\"width:5%\">");
                        mailBody.AppendFormat("</td>");
                        mailBody.AppendFormat("<td style=\"width:95%\"><div>");
                        mailBody.AppendFormat("<a  href=\"" + document.Url +
                                      "\" style=\"font-family:Arial;font-size:9pt;\"> ");
                        mailBody.AppendFormat(document.Name + "</a>");
                        mailBody.AppendFormat("</td>");
                        mailBody.AppendFormat("</tr>");
                    }
                }
            }
            mailBody.AppendFormat("<tr><td style=\"width:5%\"></td>");
            mailBody.AppendFormat("<td style=\"width:95%\"><div>");
            mailBody.AppendFormat("<a  href=\"" + Request.Url);
            if (ViewState["parentCommentId"] != null)
            {
                if (string.IsNullOrEmpty(discussionItemEntered.ParentDiscussionEntryId))
                {
                    mailBody.AppendFormat("&parentCommentId=" + discussionItemEntered.ParentDiscussionEntryId);
                }
            }
            else
            {
                mailBody.AppendFormat("&parentCommentId=" + discussionItemEntered.DiscussionEntryId);
            }
            mailBody.AppendFormat("\" style=\"font-family:Arial;font-size:15pt;\">Click Me</a>" + " to reply.");
            mailBody.AppendFormat("</td>");
            mailBody.AppendFormat("</tr>");

            // to do history of comments trail....

            mailBody.AppendFormat("</table>");
            
            string regards = "<p>Regards,</p><p> " + discussionItemEntered.EnteredBySmallName + "</p>";
            mailBody.AppendFormat(regards);
            mailBody.AppendFormat("</div>");
            if (discussionActivity.DiscussionHistory.Count > 1)
            {
                mailBody.AppendFormat("<br/>");
                mailBody.AppendFormat("<div style=\"font:1.2em; font-size:10pt; font-family:Arial, Helvetica, sans-serif;\">");
                mailBody.AppendFormat("The complete discussion except the above comment is as follows:");
                mailBody.AppendFormat("</div>");
                mailBody.AppendFormat("<br/>");
                string completeDiscussionExceptThelatestComment =GetCompleteDiscussionExceptTheLatestComment(discussionItemEntered, discussionActivity);
                mailBody.Append(completeDiscussionExceptThelatestComment);
            }
            message.IsBodyHtml = true;
            message.Body = mailBody.ToString();
            TfsUser toUser = GetToTfsUserFromListOfTfsUsers(ddlTfsUsers.Text);
            message.To.Add(toUser.MailAddress);
            FillCCListInMailMessage(message,txtCC.Text);
            string[] user = Page.User.Identity.Name.Split(new[] { '\\' });
            TfsUser currentTfsUser = GetCurrentTfsUser(user[1]);
            message.From = new MailAddress(currentTfsUser.MailAddress);
            SmtpClient smtpServer = new SmtpClient("mhub.corp.jci.com");
            smtpServer.EnableSsl = false;
            smtpServer.Send(message);
        }

        private string GetCompleteDiscussionExceptTheLatestComment(DiscussionItem discussionItemEntered, DiscussionActivity discussionActivity)
        {
            StringBuilder discussionBuilder = new StringBuilder();
            discussionBuilder.AppendFormat("<div style=\"font:1.2em; font-size:10pt; font-family:Arial, Helvetica, sans-serif; clear:both; border:1px solid #666; border-bottom:none; margin:20px 20px 50px;\">");
            discussionBuilder.AppendFormat("<table style=\"width:100%;  font-size:.9em; border-bottom:1px solid #666;\">");
            discussionBuilder.AppendFormat("<tr>");
            discussionBuilder.AppendFormat("<th style=\"padding:10px; background:#CCC; border-color: #000000; border-bottom-style: solid; border-bottom-width: 1px\">Commented By</th>");
            discussionBuilder.AppendFormat("<th style=\"padding:10px; background:#CCC; border-color: #000000; border-bottom-style: solid; border-bottom-width: 1px\">Commented For</th>");
            discussionBuilder.AppendFormat("<th style=\"padding:10px; background:#CCC; border-color: #000000; border-bottom-style: solid; border-bottom-width: 1px\">Regarding</th>");
            discussionBuilder.AppendFormat("<th style=\"padding:10px; background:#CCC; border-color: #000000; border-bottom-style: solid; border-bottom-width: 1px\">Comment</th>");
            discussionBuilder.AppendFormat("<th style=\"padding:10px; background:#CCC; border-color: #000000; border-bottom-style: solid; border-bottom-width: 1px\">Comment Date</th>");
            discussionBuilder.AppendFormat("</tr>");
            foreach(DiscussionItem currentDiscussionItem in discussionActivity.DiscussionHistory)
            {
                if(currentDiscussionItem.DiscussionEntryId!=discussionItemEntered.DiscussionEntryId)
                {
                    discussionBuilder.AppendFormat("<tr>");
                    discussionBuilder.AppendFormat("<td style=\"padding:5px 20px; border-color: #000000; border-bottom-style: solid; border-bottom-width: 1px\">" + currentDiscussionItem.EnteredBySmallName + "</td>");
                    discussionBuilder.AppendFormat("<td style=\"padding:5px 20px; border-color: #000000; border-bottom-style: solid; border-bottom-width: 1px\">" + currentDiscussionItem.EnteredFor + "</td>");
                    discussionBuilder.AppendFormat("<td style=\"padding:5px 20px; border-color: #000000; border-bottom-style: solid; border-bottom-width: 1px\">" + currentDiscussionItem.DiscussionType + "</td>");
                    discussionBuilder.AppendFormat("<td style=\"padding:5px 20px; border-color: #000000; border-bottom-style: solid; border-bottom-width: 1px\">" +Server.HtmlDecode(currentDiscussionItem.DiscussionText));
                    if (currentDiscussionItem.DocumentsAttached != null)
                    {
                        if (currentDiscussionItem.DocumentsAttached.Count > 0)
                        {
                            foreach (ActivityAttachment document in currentDiscussionItem.DocumentsAttached)
                            {
                                discussionBuilder.AppendFormat("<table>");
                                discussionBuilder.AppendFormat("<tr>");
                                discussionBuilder.AppendFormat("<td>");
                                discussionBuilder.AppendFormat("<a  href=\"" + document.Url +
                                              "\" style=\"font-family:Arial;font-size:9pt;\"> ");
                                discussionBuilder.AppendFormat(document.Name + "</a>");
                                discussionBuilder.AppendFormat("</td>");
                                discussionBuilder.AppendFormat("</tr>");
                                discussionBuilder.AppendFormat("</table>");
                            }

                        }
                    }
                    discussionBuilder.AppendFormat("</td>");
                    discussionBuilder.AppendFormat("<td style=\"padding:5px 20px; border-color: #000000; border-bottom-style: solid; border-bottom-width: 1px\">" + currentDiscussionItem.EntryDate + "</td>");
                    discussionBuilder.AppendFormat("</tr>");
                }
            }
            discussionBuilder.AppendFormat("</table>");
            discussionBuilder.AppendFormat("</div>");
            return discussionBuilder.ToString();
        }

        private TfsUser GetToTfsUserFromListOfTfsUsers(string tfsUserDisplayName)
        {
            List<TfsUser> listOfTfsUsers = GetTfsUsers();
            TfsUser selectedTfsUser = listOfTfsUsers.Find(tfsUser => tfsUser.DisplayName == tfsUserDisplayName);
            return selectedTfsUser;
        }

        private void FillCCListInMailMessage(MailMessage mailMessage,string ccString)
        {
            if(ccString==string.Empty)
                return;
            List<TfsUser> listOfTfsUsers = GetTfsUsers();
            string[] listOfTfsUserNamesinCCString = ccString.Split(new char[] {','});
            foreach(string currentTfsUserName in listOfTfsUserNamesinCCString)
            {
                if (!string.IsNullOrEmpty(currentTfsUserName))
                {
                    TfsUser currentTfsUserForCC = listOfTfsUsers.Find(tfsUser => tfsUser.DisplayName == currentTfsUserName);
                    mailMessage.CC.Add(new MailAddress(currentTfsUserForCC.MailAddress));
                }
            }
        }

        private void GetThePathOfFileToBeAttached(out string filePath,out string fileName)
        {
            string comment;
            comment = fileUploader.FileName;
            if (!fileUploader.HasFile)
            {
                filePath = string.Empty;
                fileName = string.Empty;
                return;
            }
            if (!Directory.Exists(ConfigurationManager.AppSettings["FileFolder"]))
            {
                Directory.CreateDirectory(ConfigurationManager.AppSettings["FileFolder"]);
            }
            else
            {
                DirectoryInfo directoryInfo = new DirectoryInfo(ConfigurationManager.AppSettings["FileFolder"]);
                foreach (FileInfo file in directoryInfo.GetFiles())
                {
                    file.Delete();
                }
            }
            string filePathToUpload = ConfigurationManager.AppSettings["FileFolder"] + "\\" + fileUploader.FileName;
            fileUploader.PostedFile.SaveAs(filePathToUpload);
            filePath = filePathToUpload;
            fileName = comment;
        }

        protected void repeaterDiscussionHistory_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
        {
            if (e == null) throw new ArgumentNullException("e");
            if (e.Item.ItemIndex != -1)
            {
                HtmlGenericControl divDiscussiobnText = (HtmlGenericControl)e.Item.FindControl("divDiscussiobnText");
                DiscussionItem currentDataItem = (DiscussionItem)e.Item.DataItem; 
                divDiscussiobnText.InnerHtml = Server.HtmlDecode(currentDataItem.DiscussionText);   
                if (currentDataItem.DocumentsAttached != null && currentDataItem.DocumentsAttached.Count > 0)
                {
                    HtmlTable table = CreateTableToShowTheAttachmentLinks(currentDataItem);
                    e.Item.Controls.Add(table);
                    HtmlGenericControl div = (HtmlGenericControl)e.Item.FindControl("divAttachments");
                    div.Controls.Add(table);
                }
            }
        }        

        private HtmlTable CreateTableToShowTheAttachmentLinks(DiscussionItem discussionItem)
        {
            HtmlTable table = new HtmlTable();
            HtmlTableRow tableRow;
            HtmlTableCell tableCell;
            foreach(ActivityAttachment currentAttachedDocument in discussionItem.DocumentsAttached)
            {
                tableRow=new HtmlTableRow();
                tableCell = new HtmlTableCell();
                tableCell.InnerHtml = ("<a  href=\"" + currentAttachedDocument.Url +
                                 "\" style=\"font-family:Arial;font-size:9pt;\">"+ currentAttachedDocument.Name+"</a>");
                tableRow.Cells.Add(tableCell);
                table.Rows.Add(tableRow);
            }
            return table;
        }
    }
}